package event.numberevent;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;

import assister.MathAssister;



/**rappresenta l'oggetto che gestisce l'invio degli eventi a tutti gli ascoltatore che si interessano
 * di sentire gli eventi provocati da un ListenedNumber.
 * 
 * @author koldar
 * @version 1.0
 *
 * @param <NUMBER> indica la classe numero cui il ListenedNumber opera
 * @deprecated
 */
class NumberManager<NUMBER extends  Number>{//Number> {
	
	private static final String A="A";
	private static final String B="B";
	private static final String SX_SIDE="SX_SIDE";
	private static final String DX_SIDE="DX_SIDE";

	private Vector<NumberListener<NUMBER>> Listeners;
	
	/**costruisce un nuovo oggetto che gestisce la trasmissione 
	 * 
	 * @param source
	 */
	protected NumberManager(){
		this.Listeners=new Vector<NumberListener<NUMBER>>(0,1);
	}
	protected boolean addNumberListener(NumberListener<NUMBER> TL){
		return this.Listeners.add(TL);
	}
	protected boolean removeNumberListener(NumberListener<NUMBER> TL){
		return this.Listeners.remove(TL);
	}
	@SuppressWarnings("unchecked")
	protected void fireNumberEvent(NumberEvent<NUMBER> event) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchFieldException{
		for (int num_listener=0; num_listener<this.Listeners.size();num_listener++){//scorro gli ascoltatori
			List<Class<?>> cl=Arrays.asList(this.Listeners.get(num_listener).getClass().getInterfaces());//lista di interfacce
			for (int num_interface=0;num_interface<cl.size();num_interface++){//scorro le interfacce di un ascoltatore
				Class<?> currentinterface=cl.get(num_interface);
				List<Class<?>> interfaces_of_currentinterface=Arrays.asList(currentinterface.getInterfaces());
				for (int super_interfaces=0;super_interfaces<interfaces_of_currentinterface.size();super_interfaces++){//lista delle interfacce di un interfaccia dell'ascoltatore: controllo se tale interfaccia � figlia di NumberListener
					if (interfaces_of_currentinterface.get(super_interfaces)==NumberListener.class){//l'interfaccia scelta � figlia di NumberListener
						List<Method> methodlist=Arrays.asList(currentinterface.getMethods());
						for (int o=0;o<methodlist.size();o++){
							if (MathAssister.extremis(
									((Comparable<NUMBER>)event.getActualvalue()),
									((NUMBER)currentinterface.getField(A).get(null)),
									((NUMBER)currentinterface.getField(B).get(null)),
									(Boolean)currentinterface.getField(SX_SIDE).get(null),
									(Boolean)currentinterface.getField(DX_SIDE).get(null))){
								methodlist.get(o).invoke(this.Listeners.get(num_listener),event);
							}
						}
					}
				}
			}
		}
	}
}
